import os
import time
from typing import List

from fastapi import Depends, HTTPException, APIRouter, Request, Security, Path, UploadFile, File
from sqlalchemy.orm import Session
from starlette import status

import config
from apps.blueprints.user import crud, schemas
from apps.blueprints.user.crud import authenticate_user, get_roles, update_user, get_user_by_id, updata_password, \
    user_upload_file
from apps.utils.database import get_write_db, get_read_db
from apps.extend.route import Route
from apps.utils import BaseResponse
from apps.extend.security import Token, create_access_token, jwt_get_current_user
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
import datetime
from apps.utils import BaseResponse


router = APIRouter(route_class=Route)


@router.post('/user/', response_model=schemas.User, name='注册用户')
async def create_user(user: schemas.UserCreate, db: Session = Depends(get_write_db)):
    db_user = crud.get_user_by_contact_number(db, contact_number=user.contact_number)
    if db_user:
        raise HTTPException(status_code=400, detail=f'{user.contact_number}手机号已经被注册')
    return crud.create_user(db=db, user=user)


@router.get("/users/", response_model=List[schemas.User], name='查询用户列表')
async def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_read_db),
               current_user=Depends(jwt_get_current_user)):
    users = crud.get_users(db, skip=skip, limit=limit)
    return users


@router.get("/user/{user_id}/", response_model=schemas.User, name='通过id获取用户')
async def read_user(user_id: int, db: Session = Depends(get_read_db)):
    db_user = crud.get_user_by_id(db, user_id=user_id)
    return db_user


@router.get("/user/", response_model=schemas.User, name='查看当前登录用户', tags=['用户操作'])
async def read_current_user(current_user=Depends(jwt_get_current_user)):
    return current_user


# @router.post("/users/{user_id}/items/", response_model=schemas.Item, name='创建一个item', deprecated=True)
# def create_item_for_user(
#         user_id: int, item: schemas.ItemCreate, db: Session = Depends(get_write_db)
# ):
#     return crud.create_user_item(db=db, item=item, user_id=user_id)
#
#
# @router.get("/items/", response_model=List[schemas.Item], name='查询item列表', deprecated=True)
# def read_items(skip: int = 0, limit: int = 100, db: Session = Depends(get_read_db)):
#     items = crud.get_items(db, skip=skip, limit=limit)
#     return items


@router.post("/token/", response_model=Token, name='用户登录,获取token')
async def login_for_access_token(req: Request, db: Session = Depends(get_read_db), form_data: OAuth2PasswordRequestForm = Depends()):
    # 首先校验用户信息
    user = authenticate_user(db, form_data.username, form_data.password)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Incorrect username or password",
            headers={"WWW-Authenticate": "Bearer"},
        )
    # 生成并返回token信息
    data = {
        'username': user.contact_number,
        "id": user.id,
        "is_active": user.is_active
    }
    user.last_login_date = datetime.datetime.now()
    user.last_login_ip = req.client.host
    db.commit()
    access_token = create_access_token(data=data)
    return {"access_token": access_token, "token_type": "bearer"}

#
# @router.get('/test_redis/key', name='测试redis使用')
# async def test_redis(req: Request):
#     cache = await req.app.state.cache.set('k1', 'v1')
#     return 'ok'


@router.get('/roles/', name='角色列表')
async def get_role_list(db: Session = Depends(get_read_db), skip: int = 0, limit: int = 100):
    roles = get_roles(db, skip=skip, limit=limit)
    return roles


@router.put('/user/{user_id}/', name='编辑用户信息')
async def update_user_view(user_info: schemas.UpdateUser,
                           user_id: int = Path(..., gt=0),
                           db: Session = Depends(get_read_db)
                           ):
    update_user(db, user_id=user_id, update_user=user_info)
    return BaseResponse.success(data=user_info, msg='资料编辑成功')


@router.put('/user/password/{user_id}', name='修改密码')
async def update_password_view(user_info: schemas.PasswordUser,
                           user_id: int = Path(..., gt=0),
                           db: Session = Depends(get_read_db)):
    res = updata_password(db=db, user_id=user_id, PasswordUser=user_info)
    if not res:
        raise HTTPException(status_code=400, detail='密码错误')
    return BaseResponse.success(msg='密码修改成功')


@router.post("/user/upload_files/{user_id}", name='上传头像')
async def upload_files(files: List[UploadFile] = File(...),
                       user_id: int = Path(..., gt=0),
                       db: Session = Depends(get_read_db, ),
                       ):  # 如果要上传单个文件 file: UploadFile = File(...)
    for file in files:
        contents = await file.read()
        file_name = str(time.time()) + '.jpg'
        file_path = config.IMAGE_PATH + '/user/' + file_name
        with open(file_path, 'wb') as f:
            f.write(contents)
        await user_upload_file(db, user_id, file_path)
    return BaseResponse.success(msg='头像上传成功')
